PSCI: Update state only if CPU_OFF is not denied by SPD
authorSoby Mathew <[email protected]>
Thu, 1 Oct 2015 15:46:06 +0000 (16:46 +0100)
committerSoby Mathew <[email protected]>
Tue, 6 Oct 2015 08:49:10 +0000 (09:49 +0100)
This patch fixes an issue in the PSCI framework where the affinity info
state of a core was being set to OFF even when the SPD had denied the
CPU_OFF request. Now, the state remains set to ON instead.

Fixes ARM-software/tf-issues#323

Change-Id: Ia9042aa41fae574eaa07fd2ce3f50cf8cae1b6fc

services/std_svc/psci/psci_off.c

index f565ffb7efa89ba7271ec464ec560dda6244ac4b..9ed6f0cf9bb67219b5fd7460198cca3fb0e82e3c 100644 (file)
@@ -62,7 +62,7 @@ static void psci_set_power_off_state(psci_power_state_t *state_info)
  ******************************************************************************/
 int psci_do_cpu_off(unsigned int end_pwrlvl)
 {
-       int rc, idx = plat_my_core_pos();
+       int rc = PSCI_E_SUCCESS, idx = plat_my_core_pos();
        psci_power_state_t state_info;
 
        /*
@@ -120,23 +120,27 @@ exit:
        psci_release_pwr_domain_locks(end_pwrlvl,
                                      idx);
 
-       /*
-        * Set the affinity info state to OFF. This writes directly to main
-        * memory as caches are disabled, so cache maintenance is required
-        * to ensure that later cached reads of aff_info_state return
-        * AFF_STATE_OFF.
-        */
-       flush_cpu_data(psci_svc_cpu_data.aff_info_state);
-       psci_set_aff_info_state(AFF_STATE_OFF);
-       inv_cpu_data(psci_svc_cpu_data.aff_info_state);
-
        /*
         * Check if all actions needed to safely power down this cpu have
-        * successfully completed. Enter a wfi loop which will allow the
-        * power controller to physically power down this cpu.
+        * successfully completed.
         */
-       if (rc == PSCI_E_SUCCESS)
+       if (rc == PSCI_E_SUCCESS) {
+               /*
+                * Set the affinity info state to OFF. This writes directly to
+                * main memory as caches are disabled, so cache maintenance is
+                * required to ensure that later cached reads of aff_info_state
+                * return AFF_STATE_OFF.
+                */
+               flush_cpu_data(psci_svc_cpu_data.aff_info_state);
+               psci_set_aff_info_state(AFF_STATE_OFF);
+               inv_cpu_data(psci_svc_cpu_data.aff_info_state);
+
+               /*
+                * Enter a wfi loop which will allow the power controller to
+                * physically power down this cpu.
+                */
                psci_power_down_wfi();
+       }
 
        return rc;
 }